package razor.blade;

import javafx.beans.binding.*;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.beans.property.*;
import javafx.beans.value.*;
import javafx.scene.input.*;
import javafx.scene.image.*;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.beans.property.*;
import javafx.scene.input.*;
import javafx.geometry.*;
import javafx.scene.transform.*;
import javafx.scene.effect.*;
import javafx.beans.value.*;
import tee.binding.*;
import javafx.beans.binding.*;

public class ButtonBox {
    private Numeric x;
    private Numeric y;
    private Numeric width;
    private Numeric height;
    private Node content;
    private Group root;
    private Group back;
    private Group contentGroup;
    private Group shadowGroup;
    private Task closeButtonPressed;
    private Rectangle flare;
    private Stop[] stops3;
    private LinearGradient fill3;
      private It<Color>color;
      private   Rectangle r3;
    //private double pressX = 0;
    //private double pressY = 0;
    //private Rectangle r;
    public Node node() {
        return root;
    }
    public ButtonBox x(double it) {
	x.value(it);
	return this;
    }
    public ButtonBox x(int it) {
	x.value(it);
	return this;
    }
    public Numeric x() {
	return x;
    }
    public ButtonBox x(It<Double> it) {
	x.bind(it);
	return this;
    }
    public ButtonBox y(double it) {
	y.value(it);
	return this;
    }
    public ButtonBox y(int it) {
	y.value(it);
	return this;
    }
    public Numeric y() {
	return y;
    }
    public ButtonBox y(It<Double> it) {
	y.bind(it);
	return this;
    }
    public ButtonBox width(double it) {
	width.value(it);
	return this;
    }
    public ButtonBox width(int it) {
	width.value(it);
	return this;
    }
    public Numeric width() {
	return width;
    }
    public ButtonBox width(It<Double> it) {
	width.bind(it);
	return this;
    }
    public ButtonBox height(double it) {
	height.value(it);
	return this;
    }
    public ButtonBox height(int it) {
	height.value(it);
	return this;
    }
    public Numeric height() {
	return height;
    }
    public ButtonBox height(It<Double> it) {
	height.bind(it);
	return this;
    }
    public ButtonBox color(Color it) {
	color.value(it);
	return this;
    }
    public ButtonBox color(It<Color> it) {
	color.bind(it);
	return this;
    }
    public ButtonBox content(Node n) {
        contentGroup.getChildren().clear();
        contentGroup.getChildren().add(n);
        content=n;
        adjustSize();
        adjustOpacity();
        return this;
    }
    /*public void onClick() {
        System.out.println("click");
    }*/
    public ButtonBox buttonPressed(Task it) {
        closeButtonPressed=it;
        return this;
    }
    void adjustOpacity() {
        if(content==null)return;
        if(contentGroup==null)return;
	if (flare.isHover()) {
	    back.setOpacity(1.0);
	    content.setOpacity(1.0);
	} else {
	    back.setOpacity(0.0);
	    content.setOpacity(0.5);
	}
    }
    void adjustSize() {
        //System.out.println("adjustSize");
        if(content==null)return;
        if(contentGroup==null)return;
        double contentWidth = content.getBoundsInLocal().getWidth();
        //System.out.println(contentWidth);
        double contentHeight = content.getBoundsInLocal().getHeight();
        double contentX = content.getBoundsInLocal().getMinX();
        double contentY = content.getBoundsInLocal().getMinY();
        if (contentWidth > 0 && contentHeight > 0 && width.value() > 0 && height.value() > 0) {
            double widthScale = (width.value() - 16) / contentWidth;
            double heightScale = (height.value() - 16) / contentHeight;
            double scaleSize = widthScale < heightScale ? widthScale : heightScale;
            Scale scaleTransform = new Scale(scaleSize, scaleSize, 0, 0);
            contentGroup.getTransforms().clear();
            contentGroup.getTransforms().add(scaleTransform);
            double xShift = (width.value() - contentWidth * scaleSize - 16) / 2 + 8;
            double yShift = (height.value() - contentHeight * scaleSize - 16) / 2 + 8;
            contentGroup.setTranslateX(xShift - contentX * scaleSize + x.value());
            contentGroup.setTranslateY(yShift - contentY * scaleSize + y.value());
        }
    }
    /*public ButtonBox color(Color it) {
        color.set(it);
        return this;
    }
    
    public ButtonBox color(SimpleObjectProperty<Color> it) {
        color.bindBidirectional(it);
        return this;
    }*/
    private void setColor(){
        //System.out.println(color.get());
        Color c1=new Color(
                color.value().getRed()
                ,color.value().getGreen()
                 ,       color.value().getBlue()
                ,0
                );
         Color c2=new Color(
                color.value().getRed()
                ,color.value().getGreen()
                 ,       color.value().getBlue()
                ,0.5
                );
    stops3 = new Stop[]{new Stop(0, c1), new Stop(0.5,  c2), new Stop(1,  c1)};
         //stops3 = new Stop[]{new Stop(0, Color.web("#00336600")), new Stop(0.5, Color.web("#00336666")), new Stop(1, Color.web("#00336600"))};
         fill3 = new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE, stops3);
        r3.setFill(fill3);
    }
    public ButtonBox() {
         //closeButtonPressed=null;
        x = new Numeric().value(0);
        y = new Numeric().value(0);
        color=new It<Color>().value(Color.web("#003366"));
        width = new Numeric().value(50);
        height = new Numeric().value(50);
        root = new Group();
        back = new Group();
        root.getChildren().add(back);
        shadowGroup = new Group();
        DropShadow ds = new DropShadow();
	shadowGroup.setEffect(ds);
        root.getChildren().add(shadowGroup);
        contentGroup = new Group();
        shadowGroup.getChildren().add(contentGroup);

        Rectangle r1 = new Rectangle();
        r1.xProperty().bind(new Tee<Double>(x));
        r1.yProperty().bind(new Tee<Double>(y));
        r1.heightProperty().bind(new Tee<Double>(height));
        r1.widthProperty().set(1);
        Stop[] stops1 = new Stop[]{new Stop(0, Color.web("#00000000")), new Stop(0.5, Color.web("#00000066")), new Stop(1, Color.web("#00000000"))};
        LinearGradient fill1 = new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE, stops1);
        r1.setFill(fill1);
        back.getChildren().add(r1);

        Rectangle r2 = new Rectangle();
        //r2.translateXProperty().set(1);
        r2.xProperty().bind(new Tee<Double>(x.plus(width).minus(1)));
        r2.yProperty().bind(new Tee<Double>(y));
        r2.heightProperty().bind(new Tee<Double>(height));
        r2.widthProperty().set(1);
        Stop[] stops2 = new Stop[]{new Stop(0, Color.web("#ffffff00")), new Stop(0.5, Color.web("#ffffff33")), new Stop(1, Color.web("#ffffff00"))};
        LinearGradient fill2 = new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE, stops2);
        r2.setFill(fill2);
        back.getChildren().add(r2);

         r3 = new Rectangle();
        //r3.translateXProperty().set(1);
        r3.xProperty().bind(new Tee<Double>(x.plus(1)));
        r3.yProperty().bind(new Tee<Double>(y));
        r3.heightProperty().bind(new Tee<Double>(height));
        r3.widthProperty().bind(new Tee<Double>(width.minus(2)));
        //stops3 = new Stop[]{new Stop(0, color.get()), new Stop(0.5,  color.get()), new Stop(1,  color.get())};
         //stops3 = new Stop[]{new Stop(0, Color.web("#00336600")), new Stop(0.5, Color.web("#00336666")), new Stop(1, Color.web("#00336600"))};
         //fill3 = new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE, stops3);
        //r3.setFill(fill3);
        setColor();
        back.getChildren().add(r3);
        
        ImageView view = new ImageView();
        view.setImage(new Image(this.getClass().getResourceAsStream("steelBall12.png")));
        view.xProperty().bind(new Tee<Double>(x.plus(2)));
        view.yProperty().bind(new Tee<Double>(y.plus(2)));
        root.getChildren().add(view);

        flare = new Rectangle();
        flare.xProperty().bind(new Tee<Double>(x.plus(1)));
        flare.yProperty().bind(new Tee<Double>(y));
        flare.heightProperty().bind(new Tee<Double>(height));
        flare.widthProperty().bind(new Tee<Double>(width));
        flare.setFill(Color.web("#00000001"));
        flare.setCursor(Cursor.HAND);
        root.getChildren().add(flare);

       flare.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                //onClick();
                if(closeButtonPressed!=null){closeButtonPressed.start();}
            }
        });
        flare.hoverProperty().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                adjustOpacity();
            }
        });
        /*width.addListener(new ChangeListener<Number>() {
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                adjustSize();
            }
        });
        height.addListener(new ChangeListener<Number>() {
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                adjustSize();
            }
        });
        color.addListener(new ChangeListener<Color>() {
            public void changed(ObservableValue<? extends Color> observable, Color oldValue, Color newValue) {
                setColor();
            }
        });*/
        adjustSize();
        adjustOpacity();
    }
}
